package top.rainf.support;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * @author 星环
 * @date 2023/5/7 17:00:15
 * @description 用来逐行添加Json的类，可以拼装多个Json
 */
public class JsonCreator {
    //要有以下功能
    //添加一条属性，接受字符串、数字或者JsonCreator（将另一个Json嵌套进来）
    //toString返回Json格式的字符串
    //那么可以使用建造者、懒加载，调用时才转字符串。
    //用map装，最好用有序map，或者用列表，但是需要二元组
    //存放属性名和值
    //外框拼接：{}
    //递归生成tostring。
    //这样，父类只需要调用自己的tostring，就会自动生成它的属性字符串格式。
    //要注意的是，属性有三种格式，对应在生成时使用三种策略
    //1只是简单属性，直接调用tostring，其中，
    //数字直接拼接，
    //字符串还要在外面拼接一个双引号
    //2是数组的话用[]装，
    //是对象（此处只为JsonCreator）使用{}
    //适配直接把对象转json的他人类，使用addJson
    /*
        每条数据需要一个名称，和它自己作为数据，拼接为
     */
    //linked保证插入有序，<属性名，对象值>
    private LinkedHashMap<String,Object> attrMap = new LinkedHashMap<>();


    public JsonCreator addAttr(String key,Object value){
        attrMap.put(key, value);
        return this;
    }

    /**
     * 适配JsonObject，咱不可用
     * @param key
     * @param value
     */
    public void addJson(String key,String value){
        //
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("{\n");
        Iterator<String> it = attrMap.keySet().iterator();
        while (it.hasNext()){
            String next = it.next();
            Object o = attrMap.get(next);
            buildAttr(sb,next,o);
        }
        sb.deleteCharAt(sb.length()-2);
        sb.append('}');
        return sb.toString();
    }

    private void buildAttr(StringBuilder sb, String key, Object o) {
        buildKey(sb,key);
        //前方设置完毕，设置后面的
        //值可以是对象、数组、值
        buildVal(sb,o);
        sb.append(",\n");
    }

    private void buildVal(StringBuilder sb, Object o) {
        if(o instanceof String str){
            sb.append('\"').append(str).append('\"');
        } else if(o instanceof List list){
            sb.append('[');
            for (int i = 0; i< list.size();i++) {
                buildVal(sb,list.get(i));
                if (i != list.size() - 1){
                    sb.append(',');
                }
            }
            sb.append(']');
        } else {
            sb.append(o.toString());
        }
    }

    private void buildKey(StringBuilder sb,String key){
        sb.append('\"').append(key).append('\"');
        sb.append(':');
    }
}
